/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package MF2DSolver;

import Integration.Gauss2D;
import Integration.IFunction2D;
import MathLib.triangulation.SaveStructures.TriangleL;
import MeshlessShapeFunctions.JMeshlessInterpolationFunctionLiu;
import java.util.ArrayList;

/**
 *
 * @author mark_o
 */
public class ElementMatrixGeneratorMF2DSQR {
    protected ArrayList<TriangleL> BackGroundElementsList;
    protected JMeshlessInterpolationFunctionLiu phi1;
    protected JMeshlessInterpolationFunctionLiu phi2;
    protected Gauss2D gau;
    double left;
    double right;
    double top;
    double bottom;
    double ax;
    double ay;
    double bx;
    double by;

    public ElementMatrixGeneratorMF2DSQR() {
        gau  = new Gauss2D(20);
    }

    public double getBottom() {
        return bottom;
    }

    public void setBottom(double bottom) {
        this.bottom = bottom;
    }

    public double getLeft() {
        return left;
    }

    public void setLeft(double left) {
        this.left = left;
    }

    public JMeshlessInterpolationFunctionLiu getPhi1() {
        return phi1;
    }

    public void setPhi1(JMeshlessInterpolationFunctionLiu phi1) {
        this.phi1 = phi1;
    }

    public JMeshlessInterpolationFunctionLiu getPhi2() {
        return phi2;
    }

    public void setPhi2(JMeshlessInterpolationFunctionLiu phi2) {
        this.phi2 = phi2;
    }

    public double getRight() {
        return right;
    }

    public void setRight(double right) {
        this.right = right;
    }

    public double getTop() {
        return top;
    }

    public void setTop(double top) {
        this.top = top;
    }

    public void update(){
        ax = Math.max(phi1.getXii()-phi1.getRho(), phi2.getXii()-phi2.getRho());
        ax = Math.max(ax, left);
        bx = Math.min(phi1.getXii()+phi1.getRho(), phi2.getXii()+phi2.getRho());
        bx = Math.min(right, bx);

        ay = Math.max(phi1.getYii()-phi1.getRho(), phi2.getYii()-phi2.getRho());
        ay = Math.max(ay, left);
        by = Math.min(phi1.getYii()+phi1.getRho(), phi2.getYii()+phi2.getRho());
        by = Math.min(right, by);


        ax = 0.0;
        bx = 1.0;
        ay = 0.0;
        by = 1.0;
    }

    public double generateMeElement(final IFunction2D q){
        if((ax<bx)&&(ay<by)){
            return gau.gau(ax, bx,ay, by, new  IFunction2D() {

                public double calculate(double x,double y) {
                    return phi1.calculate(x,y)*phi2.calculate(x,y)*q.calculate(x,y);
                }

                public double calculateDerivatyX(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public double calculateDerivatyY(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;

    }

    public double generateKeElement(final IFunction2D p){
        if((ax<bx)&&(ay<by)){
            return gau.gau(ax, bx,ay, by, new  IFunction2D() {

                public double calculate(double x,double y) {
                    return (phi1.calculateDiffuseDerivatyX(x,y)*phi2.calculateDiffuseDerivatyX(x,y) +
                            phi1.calculateDiffuseDerivatyY(x,y)*phi2.calculateDiffuseDerivatyY(x,y))*p.calculate(x,y);
                }

                public double calculateDerivatyX(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public double calculateDerivatyY(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;
    }

    public double generatePeElement(final IFunction2D w){
        if((ax<bx)&&(ay<by)){
            return gau.gau(ax, bx,ay, by, new  IFunction2D() {

                public double calculate(double x,double y) {
                    return (phi2.calculateDiffuseDerivatyX(x,y)+phi2.calculateDiffuseDerivatyY(x,y))*phi1.calculate(x,y)*w.calculate(x,y);
                }

                public double calculateDerivatyX(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public double calculateDerivatyY(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
        }
        return 0;
    }

    public double generateFeElement(final IFunction2D func){
        double tmpbx = Math.min(right, phi1.getXii()+phi1.getRho());
        double tmpax = Math.max(phi1.getXii()-phi1.getRho(), left);
        double tmpby = Math.min(top, phi1.getYii()+phi1.getRho());
        double tmpay = Math.max(phi1.getXii()-phi1.getRho(), bottom);
        tmpax = 0.0;
        tmpbx = 1.0;
        tmpay = 0.0;
        tmpby = 1.0;
        return gau.gau(tmpax, tmpbx,tmpay, tmpby, new  IFunction2D() {

                public double calculate(double x,double y) {
                    return (phi1.calculate(x,y))*func.calculate(x,y);
                }

                public double calculateDerivatyX(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }

                public double calculateDerivatyY(double x, double y) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            });
    }
    

}
